package scheme;
import accessstruct.AccessControlParameter;
import accessstruct.Tool;
import accessstruct.lsss.LSSSLW10Engine;
import accessstruct.parser.ParserUtils;
import it.unisa.dia.gas.jpbc.Element;
import it.unisa.dia.gas.jpbc.Pairing;
import it.unisa.dia.gas.plaf.jpbc.pairing.PairingFactory;
import util.AccessPolicyExamples;
import util.ConfigFileName;

import java.util.Base64;
import java.util.Properties;

import static accessstruct.Tool.loadPropFromFile;
public class LWBAMAABETest {
    public static void basicTest() throws Exception {
        int aaNums = 4;
        UserManageBT BT = new UserManageBT();
        ConfigFileName config = new ConfigFileName();
        int [][] accessPolicy = ParserUtils.GenerateAccessPolicy(AccessPolicyExamples.access_policy_example_3);
        String[] rhos = ParserUtils.GenerateRhos(AccessPolicyExamples.access_policy_example_3);
        //用户属性假设也是全局属性
        String[] userAttList = AccessPolicyExamples.access_policy_example_3_satisfied_1;
        //CA初始化设置用户管理树叶子节点为8也就是可以分配8个用户
        LWBAMAABE.setUp(config ,aaNums,userAttList, BT, 8);
        //访问控制参数，主要是这个ACP
        AccessControlParameter ACP = LSSSLW10Engine.generateAccessControl(accessPolicy ,rhos);
        /***********************************************Bob******************************************/
        String userID = "Bob";
        String uid = "14";
        int uidI = 14;
        LWBAMAABE.keyGen(config, userID,uidI, userAttList, aaNums, BT);
        LWBAMAABE.pxKeyGen( config,  userID,  uidI ,  userAttList , aaNums, BT);
        /***********************************************Alice******************************************/
        String userID1 = "Alice";
        String uid1 = "13";
        int uidI1 = 13;
        LWBAMAABE.keyGen(config, userID1,uidI1, userAttList, aaNums, BT);
        LWBAMAABE.pxKeyGen( config,  userID1,  uidI1 ,  userAttList , aaNums, BT);

        /********************************************密文生成阶段******************************************/
        Element message =PairingFactory.getPairing(config.getPairingParametersFileName()).getGT().newRandomElement().getImmutable();
        LWBAMAABE.offlineEncrypt(config, userAttList,aaNums, ACP,BT);
        LWBAMAABE.onlineEncrypt( config,  message, aaNums);
        /*******************************************Bob解密阶段 ******************************************/
        RSU.outsourseDecrypt( config,  userAttList,  userID,uidI,  aaNums,  ACP,BT);
        LWBAMAABE.Pair<Element, Long> res =LWBAMAABE.localDecrypt( config,  userID);
        System.out.println("解密消息:" + res.getKey());
        System.out.println("明文消息:" + message);
        if (message.isEqual(res.getKey())) {
            System.out.println("成功解密！");
        }else{
            System.out.println("解密失败！");
        }
        /***********************************假设Bob制造黑恶对其追责******************************************/
        //生成追责密文
        CA.AccountEncrypt( config,userAttList, aaNums, message,ACP, BT);
        //黑盒追责完成
        CA.blackBoxDecrypt( config,  userAttList,  userID, uidI,  aaNums, message, ACP, BT);
        //用户撤销完成撤销Bob
        CA.userRevoke(config, BT,uid);
        //CA密文更新
        CA.CACtUpdate(config, BT);
        //云服务器密文更新
        CSP.CtUpdate(config, BT);
        //重新执行Bob的解密，看是否撤销
        System.out.println("==============================重新执行Bob的解密，看是否撤销==============================");
        if(RSU.outsourseDecrypt( config,  userAttList,  userID,uidI,  aaNums,  ACP,BT) != 0)
        {
            LWBAMAABE.Pair<Element, Long> resBob =LWBAMAABE.localDecrypt( config,  userID);
            System.out.println("解密消息:" + resBob.getKey());
            System.out.println("明文消息:" + message);
            if (message.isEqual(resBob.getKey())) {
                System.out.println("成功解密！");
            }else{
                System.out.println("解密失败！");
            }
        }else{
            System.out.println("撤销用户无法正常获取数据！！！！！！！！！！！！！！！！！！！" );
        }

        /***********************************重新执行Alice的解密操作******************************************/
        System.out.println("==============================重新执行Alice的解密，看是否还可以==============================");
        RSU.outsourseDecrypt( config,  userAttList,  userID1,uidI1,  aaNums,  ACP,BT);
        LWBAMAABE.Pair<Element, Long> res1 =LWBAMAABE.localDecrypt( config,  userID1);
        System.out.println("解密消息:" + res1.getKey());
        System.out.println("明文消息:" + message);
        if (message.isEqual(res1.getKey())) {
            System.out.println("成功解密！");
        }else{
            System.out.println("解密失败！");
        }

        /***********************************新加入用户kevin******************************************/
        System.out.println("==============================新加入用户Kevin的加解密，看是否还可以==============================");
        //测试是否可以正常解密
        String userID2 = "kevin";
        String uid2 = "11";
        int uidI2 = 11;
        LWBAMAABE.keyGen(config, userID2,uidI2, userAttList, aaNums, BT);
        LWBAMAABE.pxKeyGen( config,  userID2,  uidI2 , userAttList , aaNums, BT);
        RSU.outsourseDecrypt( config,  userAttList,  userID2,uidI2,  aaNums,  ACP,BT);
        LWBAMAABE.Pair<Element, Long> res2 =LWBAMAABE.localDecrypt( config,  userID2);
        System.out.println("解密消息:" + res1.getKey());
        System.out.println("明文消息:" + message);
        if (message.isEqual(res1.getKey())) {
            System.out.println("成功解密！");
        }else{
            System.out.println("解密失败！");
        }
    }

    public static void basicTest3(int aaNums ,int attNums) throws Exception {

//        //生成发访问策略
//        String att[] =  new String[attNums];
//        for(int i = 0;i<attNums;i++){
//            att[i] = Integer.toString(i);
//        }
//        String acp = Tool.convertToAcP(att);
//        //加载配置信息
//        ConfigFileName config = new ConfigFileName();
//        //生成访问策略矩阵
//        int [][] accessPolicy = ParserUtils.GenerateAccessPolicy(acp);
//        String[] rhos = ParserUtils.GenerateRhos(acp);
//        //访问控制参数，主要是这个ACP
//        AccessControlParameter ACP = LSSSLW10Engine.generateAccessControl(accessPolicy ,rhos);
//
//        String userID = "Bob";
//        String[] userAttList = att;
//        //开始流程测试
//        LWBAMAABE.setUp(config ,aaNums,userAttList);
//        LWBAMAABE.keyGen(config, userID, userAttList, aaNums);
//        LWBAMAABE.pxKeyGen( config,  userID,  userAttList , aaNums);
//        Element message =PairingFactory.getPairing(config.getPairingParametersFileName()).getGT().newRandomElement().getImmutable();
//        LWBAMAABE.offlineEncrypt(config, userAttList, userID, aaNums, ACP);
//        LWBAMAABE.onlineEncrypt( config,  message, aaNums);
//        RSU.outsourseDecrypt( config,  userAttList,  userID,  aaNums, accessPolicy, rhos, ACP,message);
//        LWBAMAABE.Pair<Element, Long> res =LWBAMAABE.localDecrypt( config,  userID);
//        System.out.println("解密消息:" + res.getKey());
//        System.out.println("明文消息:" + message);
//        if (message.isEqual(res.getKey())) {
//            System.out.println("成功解密！");
//        }else{
//            System.out.println("解密失败！");
//        }

    }

    public static void basicTest4() throws Exception {
        //固定AA数量为5，测试分别管理 5 10 15 20 25 30 35 40 个属性的时间
        for(int i = 5;i<5*8;i+=5){
            System.out.println("*************************************属性数量是 "+(5*i)+" *************************************");
            basicTest3( 5 ,5*i );//多权威外包解密测试
        }
    }
    public static void main(String[] args) throws Exception {
        basicTest();//单权威测试


    }

}
